package com.ruoyi.safe.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.ruoyi.common.core.domain.entity.CommonCheckType;
import com.ruoyi.common.core.domain.entity.ListType;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.ListTypeNameEnum;
import com.ruoyi.common.utils.*;
import com.ruoyi.safe.domain.*;
import com.ruoyi.safe.domain.dto.BizExcludePlanDTO;
import com.ruoyi.safe.domain.dto.BizExcludePlanTaskDTO;
import com.ruoyi.safe.domain.vo.BizExcludePlanDetailVO;
import com.ruoyi.safe.domain.vo.BizExcludePlanVO;
import com.ruoyi.safe.mapper.*;
import com.ruoyi.safe.service.IBizExcludePlanService;
import com.ruoyi.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 隐患风险排查计划Service业务层处理
 *
 * @author buxi
 * @date 2023-11-16
 */
@Service
@RequiredArgsConstructor
public class BizExcludePlanServiceImpl implements IBizExcludePlanService {

    private final BizExcludePlanMapper bizExcludePlanMapper;

    private final CommonCheckTypeMapper commonCheckTypeMapper;

    private final BizDutyRegionMapper bizDutyRegionMapper;

    private final SysUserMapper sysUserMapper;

    private final ListTypeMapper listTypeMapper;

    private final BizExcludePlanTaskMapper bizExcludePlanTaskMapper;

    private final BizProjectCheckRecordMapper bizProjectCheckRecordMapper;

    /**
     * 查询隐患风险排查计划
     *
     * @param id 隐患风险排查计划主键
     * @return 隐患风险排查计划
     */
    @Override
    public BizExcludePlan selectBizExcludePlanById(Long id) {

        BizExcludePlan bizExcludePlan = bizExcludePlanMapper.selectBizExcludePlanById(id);

        bizExcludePlan.setUserIds(bizExcludePlan.getBizExcludeUserList().stream()
                .map(BizExcludeUser::getUserId)
                .collect(Collectors.toList()));
        bizExcludePlan.setBizExcludeUserList(null);
        bizExcludePlan.setRegionIds(bizExcludePlan.getBizExcludeRegionList().stream()
                .map(BizExcludeRegion::getRegionId)
                .map(String::valueOf)
                .collect(Collectors.toList()));
        bizExcludePlan.setBizExcludeRegionList(null);

        if (StringUtils.isNotNull(bizExcludePlan.getStartDate()) && StringUtils.isNotNull(bizExcludePlan.getEndDate())) {
            bizExcludePlan.setDateRange(new Date[]{bizExcludePlan.getStartDate(), bizExcludePlan.getEndDate()});
            bizExcludePlan.setStartDate(null);
            bizExcludePlan.setEndDate(null);
        }

        return bizExcludePlan;
    }

    /**
     * 查询隐患风险排查计划列表
     *
     * @param bizExcludePlan 隐患风险排查计划
     * @return 隐患风险排查计划
     */
    @Override
    public List<BizExcludePlan> selectBizExcludePlanList(BizExcludePlan bizExcludePlan) {

        return bizExcludePlanMapper.selectBizExcludePlanList(bizExcludePlan);
    }

    @Override
    public List<BizExcludePlanVO> selectBizExcludePlanListVO(BizExcludePlanDTO bizExcludePlan) {
        List<BizExcludePlanVO> bizExcludePlanVOS = bizExcludePlanMapper.selectBizExcludePlanListVO(bizExcludePlan);
        bizExcludePlanVOS.forEach(plan -> {
            if (StringUtils.isNotNull(plan.getStartDate()) && StringUtils.isNotNull(plan.getEndDate())) {
                plan.setDateRange(new Date[]{plan.getStartDate(), plan.getEndDate()});
            }
            List ids = new ArrayList();
            if(plan.getRoleId()!=null){
                ids.add(Long.parseLong(plan.getRoleId()));
            }
            plan.setUserIds(ids);
        });
        return bizExcludePlanVOS;
    }

    /**
     * 新增隐患风险排查计划
     *
     * @param bizExcludePlan 隐患风险排查计划
     * @return 结果
     */
    @Transactional
    @Override
    public int insertBizExcludePlan(BizExcludePlan bizExcludePlan) {
        LoginUser loginUser = SecurityUtils.getLoginUser()     ;
        bizExcludePlan.setCreateBy(loginUser.getUser().getUserName());
        bizExcludePlan.setCreateTime(DateUtils.getNowDate());
        return bizExcludePlanMapper.insertPlan(bizExcludePlan);
    }

    /**
     * 修改隐患风险排查计划
     *
     * @param bizExcludePlan 隐患风险排查计划
     * @return 结果
     */
    @Transactional
    @Override
    public int updateBizExcludePlan(BizExcludePlan bizExcludePlan) {

        setUpdateByAndTime(bizExcludePlan);
        checkIsTask(bizExcludePlan);

        bizExcludePlanMapper.deleteBizExcludeUserByExcludePlanId(bizExcludePlan.getId());
        insertBizExcludeUser(bizExcludePlan);
        bizExcludePlanMapper.updateBizExcludePlan(bizExcludePlan);
        BizExcludePlan bizExcludePlan1 = bizExcludePlanMapper.selectBizExcludePlanById(bizExcludePlan.getId());
        checkIsTask(bizExcludePlan1);
        bizExcludePlanMapper.updateBizExcludePlan(bizExcludePlan1);
        return 1;
    }

    /**
     * 批量删除隐患风险排查计划
     *
     * @param ids 需要删除的隐患风险排查计划主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBizExcludePlanByIds(Long[] ids) {
        bizExcludePlanMapper.deleteBizExcludeUserByExcludePlanIds(ids);
        bizExcludePlanMapper.deleteBizExcludeRegionByExcludePlanIds(ids);
        return bizExcludePlanMapper.deleteBizExcludePlanByIds(ids);
    }

    @Override
    @Transactional
    public int updateBatchByIds(BizExcludePlan bizExcludePlan) {

        setUpdateByAndTime(bizExcludePlan);

        Long[] ids = bizExcludePlan.getIds().toArray(new Long[0]);

        if (CollectionUtils.isEmpty(bizExcludePlan.getIds())) {
            List<Long> collect = bizExcludePlanMapper.selectBizExcludePlanList(bizExcludePlan).stream()
                    .map(BizExcludePlan::getId)
                    .collect(Collectors.toList());
            ids = collect.toArray(new Long[0]);
            bizExcludePlan.setIds(collect);
        }
        if (StringUtils.isNotEmpty(bizExcludePlan.getUserIds())) {
            bizExcludePlanMapper.deleteBizExcludeUserByExcludePlanIds(ids);
            insertBizExcludeUser(bizExcludePlan);
        }
        if (StringUtils.isNotEmpty(bizExcludePlan.getRegionIds())) {
            bizExcludePlanMapper.deleteBizExcludeRegionByExcludePlanIds(ids);
            insertBizExcludeRegion(bizExcludePlan);
        }
        bizExcludePlanMapper.updateBatchByIds(bizExcludePlan);
        List<BizExcludePlan> bizExcludePlanList = bizExcludePlanMapper.selectBizExcludePlanByIds(bizExcludePlan.getIds());
        bizExcludePlanList.forEach(this::checkIsTask);
        bizExcludePlanMapper.updateIsTaskByIds(bizExcludePlanList);
        return 1;

    }

    @Override
    public List<BizExcludePlanDetailVO> selectBizExcludePlanDetailListVO(BizExcludePlanTask bizExcludePlanTask) {

        if (StringUtils.isEmpty(bizExcludePlanTask.getListType()) || StringUtils.isNull(bizExcludePlanTask.getProjectId())) {
            return new ArrayList<>();
        }
        List<ListType> listTypes = listTypeMapper.selectListTypeList(new ListType());
        // 查询所有区域
        List<BizDutyRegion> bizDutyRegions = bizDutyRegionMapper.selectBizDutyRegionList(new BizDutyRegion(bizExcludePlanTask.getProjectId()));

        // 查询所有用户
        List<SysUser> sysUsers = sysUserMapper.selectUserList(new SysUser());

        // 查询对应的表名
        String dictLabel = DictUtils.getDictLabel("list_root_type", bizExcludePlanTask.getListType());
        String tableName = ListTypeNameEnum.getName(dictLabel);

        // 构建查询条件
        BizExcludePlanTaskDTO bizExcludePlanTaskDTO = new BizExcludePlanTaskDTO();
        bizExcludePlanTaskDTO.setProjectId(bizExcludePlanTask.getProjectId());
        bizExcludePlanTaskDTO.setListType(bizExcludePlanTask.getListType());
        bizExcludePlanTaskDTO.setPageSize(Convert.toInt(ServletUtils.getParameter("pageSize"), 10));
        bizExcludePlanTaskDTO.setPageNum(Convert.toInt(ServletUtils.getParameter("pageNum"), 1));
        bizExcludePlanTaskDTO.setTableName(tableName);
        bizExcludePlanTaskDTO.setUserId(bizExcludePlanTask.getUserId());
//        bizExcludePlanTaskDTO.setRiskLevel(StringUtils.isNotEmpty(bizExcludePlanTask.getRiskLevel()) ? bizExcludePlanTask.getRiskLevel() : null);
        bizExcludePlanTaskDTO.setDateRange(StringUtils.isNotEmpty(bizExcludePlanTask.getDateRange()) ? bizExcludePlanTask.getDateRange() : null);
        bizExcludePlanTaskDTO.setDateType(StringUtils.isNotEmpty(bizExcludePlanTask.getDateType()) ? bizExcludePlanTask.getDateType() : null);

        // 查询所有排查计划
        List<BizExcludePlanVO> bizExcludePlanVOS = bizExcludePlanMapper.selectBizExcludePlanListVOList2(bizExcludePlanTaskDTO);

        if (CollectionUtils.isEmpty(bizExcludePlanVOS)) {
            return new ArrayList<>();
        }

        // 获取计划id列表
        List<Long> planIds = bizExcludePlanVOS.stream().map(BizExcludePlanVO::getId).collect(Collectors.toList());
        //根据ids查询所有计划任务
        List<BizExcludePlanTask> bizExcludePlanTasks = bizExcludePlanTaskMapper.selectBizExcludePlanTaskListByPlanIds(BizExcludePlanTaskDTO
                .builder()
                .ids(planIds)
                .projectId(bizExcludePlanTask.getProjectId()).listType(bizExcludePlanTask.getListType())
                .build());

        List<Long> taskIds = bizExcludePlanTasks.stream().map(BizExcludePlanTask::getId).collect(Collectors.toList());

        List<BizProjectCheckRecord> bizProjectCheckRecords = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(taskIds)) {

            bizProjectCheckRecords = bizProjectCheckRecordMapper.selectBizProjectCheckRecordByTaskIds(bizExcludePlanTask.getProjectId(), taskIds, new ArrayList<>());

        }


        // 查询对应人员和区域
        List<BizExcludeUser> bizExcludeUsers = StringUtils.isNotEmpty(planIds) ? bizExcludePlanMapper.selectBizExcludeUserList(planIds) : new ArrayList<>();
        List<BizExcludeRegion> bizExcludeRegionList = StringUtils.isNotEmpty(planIds) ? bizExcludePlanMapper.selectBizExcludeRegionList(planIds) : new ArrayList<>();

        // 构建结果集
        List<BizProjectCheckRecord> finalBizProjectCheckRecords = bizProjectCheckRecords;
        return bizExcludePlanVOS.stream().map(plan -> {
            plan.setDateRange(new Date[]{plan.getStartDate(), plan.getEndDate()});

            List<Long> userIds = bizExcludeUsers.stream()
                    .filter(user -> plan.getId().equals(user.getExcludePlanId()))
                    .map(BizExcludeUser::getUserId)
                    .collect(Collectors.toList());

            List<Long> regionIds = bizExcludeRegionList.stream()
                    .filter(region -> plan.getId().equals(region.getExcludePlanId()))
                    .map(BizExcludeRegion::getRegionId)
                    .collect(Collectors.toList());

            BizExcludePlanDetailVO bizExcludePlanDetailVO = new BizExcludePlanDetailVO();
            BeanUtil.copyProperties(plan, bizExcludePlanDetailVO);

            bizExcludePlanDetailVO.setRegionName(bizDutyRegions.stream()
                    .filter(region -> regionIds.contains(region.getId()))
                    .map(BizDutyRegion::getRegionName)
                    .collect(Collectors.joining(";")));

            bizExcludePlanDetailVO.setUserName(sysUsers.stream()
                    .filter(user -> userIds.contains(user.getUserId()))
                    .map(SysUser::getNickName)
                    .collect(Collectors.joining(",")));

            String typeNames = listTypes.stream().sorted(Comparator.comparing(ListType::getTypeNo))
                    .filter(listType -> Arrays.asList(plan.getAncestors().split(",")).contains(listType.getTypeNo()))
                    .collect(Collectors.toList()).stream()
                    .map(ListType::getTypeName).collect(Collectors.joining("/"));

            bizExcludePlanDetailVO.setTypeName(typeNames);
            bizExcludePlanDetailVO.setDateType(commonCheckTypeMapper.selectListTypeByTypeNo(Long.valueOf(plan.getDateType())).getCheckTypeName());
            List<Long> taskList = bizExcludePlanTasks.stream().filter(s -> s.getPlanId().equals(plan.getId())).map(BizExcludePlanTask::getId).collect(Collectors.toList());
            List<BizProjectCheckRecord> bizProjectCheckRecordList = finalBizProjectCheckRecords.stream().filter(s -> taskList.contains(s.getProjectCheckId())).collect(Collectors.toList());
            //已排查数量
            bizExcludePlanDetailVO.setExcludeCount(bizProjectCheckRecordList.stream().filter(s -> Arrays.asList("1","2","3","4").contains(s.getHiddenDangerStatus())).count());
            //未排施工数量
            bizExcludePlanDetailVO.setNotConstructionCount(bizProjectCheckRecordList.stream().filter(s -> "5".equals(s.getHiddenDangerStatus())).count());
            //产生隐患数量
            bizExcludePlanDetailVO.setDangerCount(bizProjectCheckRecordList.stream().filter(s -> Arrays.asList("1","2","3").contains(s.getHiddenDangerStatus())).count());
            //未销项数量
            bizExcludePlanDetailVO.setNotClearCount(bizProjectCheckRecordList.stream().filter(s -> Arrays.asList("1","2").contains(s.getHiddenDangerStatus())).count());
            return bizExcludePlanDetailVO;
        }).collect(Collectors.toList());
    }


    /**
     * 删除隐患风险排查计划信息
     *
     * @param id 隐患风险排查计划主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBizExcludePlanById(Long id) {
        bizExcludePlanMapper.deleteBizExcludeUserByExcludePlanId(id);
        bizExcludePlanMapper.deleteBizExcludeRegionByExcludePlanId(id);
        return bizExcludePlanMapper.deleteBizExcludePlanById(id);
    }

    /**
     * 新增隐患风险排查计划人员主子信息
     *
     * @param bizExcludePlan 隐患风险排查计划对象
     */
    private void insertBizExcludeUser(BizExcludePlan bizExcludePlan) {

        if (StringUtils.isNotNull(bizExcludePlan.getId()) && !CollectionUtils.isEmpty(bizExcludePlan.getUserIds())) {

            List<BizExcludeUser> list = bizExcludePlan.getUserIds().stream()
                    .map(userId -> {
                        BizExcludeUser user = new BizExcludeUser();
                        user.setExcludePlanId(bizExcludePlan.getId());
                        user.setUserId(userId);
                        return user;
                    })
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(list)) {
                bizExcludePlanMapper.batchBizExcludeUser(list);
            }
        }

        if (!CollectionUtils.isEmpty(bizExcludePlan.getIds()) && !CollectionUtils.isEmpty(bizExcludePlan.getUserIds())) {
            List<BizExcludeUser> list = bizExcludePlan.getIds().stream()
                    .flatMap(id -> bizExcludePlan.getUserIds().stream().map(usedId -> {
                        BizExcludeUser user = new BizExcludeUser();
                        user.setExcludePlanId(id);
                        user.setUserId(usedId);
                        return user;
                    }))
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(list)) {
                bizExcludePlanMapper.batchBizExcludeUser(list);
            }
        }


    }

    /**
     * 新增隐患风险排查计划人员主子信息
     *
     * @param bizExcludePlan 隐患风险排查计划对象
     */
    private void insertBizExcludeRegion(BizExcludePlan bizExcludePlan) {
        if (StringUtils.isNotNull(bizExcludePlan.getId()) && !CollectionUtils.isEmpty(bizExcludePlan.getRegionIds())) {

            List<BizExcludeRegion> list = bizExcludePlan.getRegionIds().stream()
                    .map(regionId -> {
                        BizExcludeRegion region = new BizExcludeRegion();
                        region.setExcludePlanId(bizExcludePlan.getId());
                        region.setRegionId(Long.valueOf(regionId));
                        return region;
                    })
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(list)) {
                bizExcludePlanMapper.batchBizExcludeRegion(list);
            }
        }
        if (!CollectionUtils.isEmpty(bizExcludePlan.getIds()) && !CollectionUtils.isEmpty(bizExcludePlan.getRegionIds())) {
            List<BizExcludeRegion> list = bizExcludePlan.getIds().stream()
                    .flatMap(id -> bizExcludePlan.getRegionIds().stream().map(regionId -> {
                        BizExcludeRegion region = new BizExcludeRegion();
                        region.setExcludePlanId(id);
                        region.setRegionId(Long.valueOf(regionId));
                        return region;
                    }))
                    .collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(list)) {
                bizExcludePlanMapper.batchBizExcludeRegion(list);
            }
        }

    }

    /**
     * 设置修改人, 修改时间, 开始时间, 结束时间,
     */
    private void setUpdateByAndTime(BizExcludePlan bizExcludePlan) {
        //设置修改人
        bizExcludePlan.setUpdateBy(SecurityUtils.getUsername());
        bizExcludePlan.setUpdateTime(DateUtils.getNowDate());
        //设置开始时间和结束时间
        if (StringUtils.isNotEmpty(bizExcludePlan.getDateRange())) {
            bizExcludePlan.setStartDate(bizExcludePlan.getDateRange()[0]);
            bizExcludePlan.setEndDate(bizExcludePlan.getDateRange()[1]);
        }
    }

    /**
     * 判断是否可以生成任务
     */
    private void checkIsTask(BizExcludePlan bizExcludePlan) {

        // 如果开始时间和结束时间不为空, 排查频次不为空, 时间类型不为空, 人员列表不为空, 区域列表不为空, 则设置为允许生成任务
        if (StringUtils.isNotNull(bizExcludePlan.getStartDate())
                && StringUtils.isNotNull(bizExcludePlan.getEndDate())
                && StringUtils.isNotNull(bizExcludePlan.getExcludeFrequency())
                && StringUtils.isNotEmpty(bizExcludePlan.getDateType())) {
            bizExcludePlan.setIsTask("1");
        } else {
            bizExcludePlan.setIsTask("0");
        }
    }
}
